package com.xbdun.web.validatebmp.frame.gateway;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import com.alibaba.fastjson.JSONObject;
import com.xbdun.common.api.AbXbdUnMacRequest;
import com.xbdun.common.api.XbdUnObjectResult;
import com.xbdun.common.enums.XbdunPkgEnum;
import com.xbdun.common.exceptions.BizException;
import com.xbdun.common.util.MacUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 公共基础类
 * @author <a href="zhanggt@cstonline.com">张国涛</a>
 * @createTime 2016年4月29日 下午5:18:59
 */
@Slf4j
public abstract class AbWayService<T> implements IBaseWayService<T>{
	public AbWayService(){}
	
	@SuppressWarnings("unchecked")
	public final XbdUnObjectResult execute(HttpServletRequest requst,HttpServletResponse response,BaseMacRequest macRequest,Object reallyObject)throws BizException{
		StringBuilder sbParams = new StringBuilder();
		//先验证基础参数是否合法
		doValidate((T)reallyObject,sbParams);
		if(sbParams.length()>0){
			XbdUnObjectResult result = XbdUnObjectResult.newInstance();
			//参数错误
			result.setBizException(BizException.PARAM_CHKE_FAIL.newInstance("%s",sbParams.toString()));
			sbParams.setLength(0);
			sbParams = null;
			
			return result;
		}
		sbParams.setLength(0);
		sbParams = null;
		XbdunPkgEnum xbdunPkgEnum = XbdunPkgEnum.getEnum(macRequest.getPkgName());
		if(null==xbdunPkgEnum){throw BizException.SECRET_UNDEFINITION;}
		//判断签名是否合法
		Map<String, String> putAllMp = putAllMp(macRequest,(T)reallyObject);
		String mac = MacUtil.mapToSecretMac(putAllMp,getIgnores(), macRequest.getTimestamp(),xbdunPkgEnum.getAccount(),xbdunPkgEnum.getSecritVal());
		if(!macRequest.getMac().equals(mac)){
			//记录非法访问
			log.info("访问签名错误,入参:"+JSONObject.toJSONString(reallyObject));
			XbdUnObjectResult result = XbdUnObjectResult.newInstance();
			result.setBizException(BizException.SECRET_MATCH_FAIL);
			return result; 
		}
		//释放资源
		putAllMp.clear();
		putAllMp = null;
		return this.doProcess(requst,response,(T)reallyObject,xbdunPkgEnum);
	}
	
	public void doValidate(final T model,final StringBuilder refMsg){};

	public String[] getIgnores() {return MacUtil.IGNORES;}
	
	//将多个Map合并到一个Map中
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map<String,String> putAllMp(AbXbdUnMacRequest macRequest,T model){
		Map<String,String> joinMap = new HashMap<String,String>();
		try{
			Map describe = BeanUtils.describe(macRequest);
			if(null!=describe&&!describe.isEmpty()){
				joinMap = new HashMap<String,String>();
				
				joinMap.putAll(describe);
				
				describe = BeanUtils.describe(model);
				joinMap.putAll(describe);
			}
			
		}catch(Exception ex){if(null!=joinMap)joinMap.clear();}
		
		return joinMap;
	}
	
	/*@PreDestroy
	public final void preDestroyCach(){
		if(null!=localCashTemp&&!localCashTemp.isEmpty()){
			System.out.println("开始释放缓存资源秘钥资源["+localCashTemp.size()+"]");
			localCashTemp.clear();localCashTemp = null;
			System.out.println("结束释放缓存资源成功");
		}
	}*/
}
